package com.tvunetworks.center.user.service.impl;

import com.github.pagehelper.PageInfo;
import com.tvunetworks.center.common.feign.UserFeignInterface;
import com.tvunetworks.center.common.model.ListDeviceParam;
import com.tvunetworks.center.common.util.MyUtil;
import com.tvunetworks.center.common.util.Result;
import com.tvunetworks.center.common.util.ResultUtil;
import com.tvunetworks.center.gs.model.Device;
import com.tvunetworks.center.user.mapper.OverWatchMapper;
import com.tvunetworks.center.user.model.OverWatch;
import com.tvunetworks.center.user.model.param.PageOverWatchParam;
import com.tvunetworks.center.user.model.param.UpdateOverWatchParam;
import com.tvunetworks.center.user.model.vo.OverWatchDeviceVo;
import com.tvunetworks.center.user.model.vo.OverWatchVo;
import com.tvunetworks.center.user.service.OverWatchService;
import com.tvunetworks.center.user.service.feign.DeviceFeignService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Etan Yang
 * @data: 6/17/2020 9:52 AM
 * @program: tvucc-aggregator
 * @description:
 */
@Service
public class OverWatcherServiceImpl implements OverWatchService {

    @Autowired
    private OverWatchMapper overWatchMapper;
    @Autowired
    private UserFeignInterface userFeignInterface;
    @Autowired
    private DeviceFeignService deviceFeignService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateOverWatch(UpdateOverWatchParam param) {
        //0.校验
        if (StringUtils.isEmpty(param.getRid()) && StringUtils.isEmpty(param.getTid())) {
            return 1;
        }
        if (param.getMaxConnect() <= 0) {
            return 2;
        }
        if (param.getCode().length() != 6) {
            return 3;
        }
        //1.查询该rid
        OverWatch overWatch;
        if (StringUtils.isNotEmpty(param.getRid())) {
            overWatch = overWatchMapper.getOverWatchByRid(param.getRid());
        }else {
            overWatch = overWatchMapper.getOverWatchByTid(param.getTid());
        }
        if (overWatch == null) {
            return 4;
        }
        OverWatch overWatchByCode = overWatchMapper.getOverWatchByCode(param.getCode());
        if (overWatchByCode != null && !overWatchByCode.getId().equalsIgnoreCase(overWatch.getId())) {
            return 5;
        }
        //2.修改参数
        overWatchMapper.updateMaxNumAndCode(overWatch.getId(), param.getMaxConnect(), param.getCode());
        return 0;
    }

    @Override
    public Result<OverWatchVo> loginOverWatch(String code) {
        //1.根据code查询
        OverWatch overWatch = overWatchMapper.getOverWatchByCode(code);
        if (overWatch == null) {
            return ResultUtil.error("81002006", "Invalid access code. Please try again");
        }
        if (overWatch.getCurrConnect() >= overWatch.getMaxConnect()) {
            return ResultUtil.error("81002007", "The number of viewers has reached the limit");
        }
        //3.返回结果
        OverWatchVo overWatchVo = new OverWatchVo();
        overWatchVo.setCode(overWatch.getCode());
        overWatchVo.setId(overWatch.getId());
        overWatchVo.setTid(overWatch.getTid());
        overWatchVo.setRid(overWatch.getRid());
        return ResultUtil.success(overWatchVo);
    }

    @Override
    public int checkCode(String code) {
        OverWatch overWatch = overWatchMapper.getOverWatchByCode(code);
        if (overWatch != null) {
            return 1;
        }
        return 0;
    }

    @Override
    public PageInfo<OverWatchDeviceVo> pageDeviceRByUser(PageOverWatchParam param, String userId) {
        //0.校验
        if (param.getPageNum() <= 0) {
            param.setPageNum(1);
        }
        if (param.getPageSize() <= 0) {
            param.setPageSize(20);
        }
        List<OverWatchDeviceVo> overWatchDeviceVos = new ArrayList<>();
        //1.获取该用户的R/T
        List<String> deviceList;
        if ("R".equalsIgnoreCase(param.getType())) {
            deviceList = userFeignInterface.listUserRids(userId);
        } else if ("T".equalsIgnoreCase(param.getType())) {
            deviceList = userFeignInterface.listUserTids(userId);
        }else {
            return new PageInfo<>(overWatchDeviceVos);
        }
        if (CollectionUtils.isEmpty(deviceList)) {
            return new PageInfo<>(overWatchDeviceVos);
        }
        //2.获取R/T对应的device信息
        int startIndex = (param.getPageNum() - 1) * param.getPageSize();
        List<String> needDeviceList = deviceList.stream().skip(startIndex).limit(param.getPageSize()).collect(Collectors.toList());
        ListDeviceParam listDeviceParam = new ListDeviceParam(needDeviceList);
        List<Device> devices = deviceFeignService.listCurrentDevice(listDeviceParam);

        if (!CollectionUtils.isEmpty(devices)) {
            for (Device device : devices) {
                OverWatchDeviceVo overWatchDeviceVo = new OverWatchDeviceVo();
                overWatchDeviceVo.setDevice(device);
                OverWatch overWatch;
                if ("R".equalsIgnoreCase(param.getType())) {
                    overWatch = overWatchMapper.getOverWatchByRid(device.getPeerId());
                } else {
                    overWatch = overWatchMapper.getOverWatchByTid(device.getPeerId());
                }
                //3.数据库中没有信息则添加进数据库中
                if (overWatch == null) {
                    overWatch = new OverWatch();
                    overWatch.setUserid(userId);
                    overWatch.setId(MyUtil.getUUID());
                    if ("R".equalsIgnoreCase(param.getType())) {
                         overWatch.setRid(device.getPeerId());
                    } else {
                        overWatch.setTid(device.getPeerId());
                    }
                    overWatchMapper.insertSelective(overWatch);
                }
                overWatchDeviceVo.setOverWatch(overWatch);
                overWatchDeviceVos.add(overWatchDeviceVo);
            }
        }
        PageInfo<OverWatchDeviceVo> pageInfo = new PageInfo<>(overWatchDeviceVos);
        pageInfo.setTotal(deviceList.size());
        return pageInfo;
    }

    @Override
    public int checkLoginCodeChange(String rid, String code) {
        OverWatch overWatch = overWatchMapper.getOverWatchByRidAndCode(rid, code);
        if (overWatch == null) {
            return 1;
        }
        return 0;
    }

    @Override
    public int updateCurrConnectNum(String rid, boolean numFlag) {
        OverWatch overWatch = overWatchMapper.getOverWatchByRid(rid);
        if (overWatch == null) {
            return 1;
        }
        int currConnect = overWatch.getCurrConnect();
        if (numFlag) {
            currConnect = currConnect + 1;
        }else {
            currConnect = currConnect - 1;
        }
        overWatchMapper.updateCurrConnect(rid, currConnect);
        return 0;
    }

    @Override
    public boolean checkCurrConnectCount(String rid) {
        OverWatch overWatchByRid = overWatchMapper.getOverWatchByRid(rid);
        if (overWatchByRid == null) {
            return false;
        }
        Integer maxConnect = overWatchByRid.getMaxConnect();
        Integer currConnect = overWatchByRid.getCurrConnect();
        if (maxConnect != null) {
            return currConnect == null || currConnect < maxConnect;
        }
        return false;
    }
}
